Synchronization of Asynchronous Image Pipelines

카메라 동기화

VisualApplets 의 강력한 기능 중 하나는 서로 다른 카메라 소스의 영상을 합성하는 것입니다. 다음에서는 이를 수행하는 방법을 알아보겠습니다.

  1. 카메라 소스 전환
  2. 두 대의 카메라로 촬영한 영상을 합성하다
  3. 카메라 영상을 멀티플렉싱한다
  4. 두 대의 카메라에 찍힌 이미지를 합치기

Switch Between two Cameras

두 대의 카메라를 전환하려면 두 개의 카메라 모듈을 포함하는 간단한 설계가 필요합니다. VisualApplets 의 SourceSelector 연산자( ‘SourceSelector’ 참조)를 사용하면 두 개의 비동기 소스 간에 전환할 수 있습니다. 이 연산자는 입력 중 하나를 선택하고, 다른 입력의 데이터는 버립니다. 입력 중 하나가 선택되면, 나머지 입력들은 Trash 연산자에 연결된 것처럼 동작합니다. 데이터 수집이 진행 중일 때도 입력을 전환할 수 있습니다. 이 연산자는 새로운 프레임이 시작될 때 전환을 수행합니다. 두 입력의 프레임 속도와 이미지 크기는 동일할 필요가 없습니다.

VisualApplets 두 대의 카메라를 전환할 수 있도록 설계됨

그림 208. 두 대의 카메라 간 전환을 위한 VisualApplets 설계


두 카메라 소스의 이미지 데이터 결합 - 오버레이 블렌드 빌드

다음에서는 두 카메라의 이미지 데이터를 어떻게 합치는지 살펴보겠습니다. 이 예제에서는 오버레이 블렌딩을 사용하여 두 이미지를 합칩니다.

이 예제의 사양은 다음과 같습니다:

  • 카메라: 기본 구성 모드의 CameraLink RGB 영역 스캔 카메라 2대
  • 해상도: 1024 x 1024 픽셀
  • 오버레이 블렌드:

    식 1. 오버레이 블렌드


  1. 기본 연산자

    다음 그림과 같이 설계의 기본 연산자부터 시작합니다. 모든 기본 매개변수와 링크 속성을 사용할 수 있습니다.

  2. Synchronization

    다음으로 두 카메라의 데이터 스트림을 동기화해야 합니다. 이는 SYNC 연산자를 사용하면 간단히 수행할 수 있습니다. SYNC 연산자는 출력이 완벽하게 동기화되도록 입력을 제어합니다. 보시다시피, 동기화 전에 두 개의 버퍼 모듈을 사용했습니다. 두 카메라가 100% 동기화되어 있다고 보장할 수 없기 때문에 이 모듈들을 사용해야 합니다.

    이미지 데이터를 동기화했지만, 여전히 몇 가지 제약 사항에 유의해야 합니다:

    • 두 카메라의 프레임 수, 즉 프레임 속도는 동일해야 합니다. 한 카메라의 프레임 속도가 다른 카메라보다 높을 경우, ImageBuffer 모듈 중 하나가 일부 이미지를 저장해야 하므로 오버플로우 상태가 발생할 수 있습니다. 따라서 장시간 촬영 시, 두 카메라 모두 동일한 프레임 속도로 프레임을 캡처해야 합니다. 트리거 시스템을 사용하면 이를 보장할 수 있습니다.

    • 두 카메라의 ROI 이미지 크기와 위치는 서로 다를 수 있습니다. SYNC 연산자는 매개변수 설정에 따라, 더 작은 이미지를 더 큰 이미지의 크기로 자동으로 확장하거나 더 큰 이미지를 잘라냅니다. 자세한 내용은 SYNC 연산자 설명을 참조하십시오: ('SYNC')
  3. 오버레이-블렌드

    마지막으로 두 이미지를 합치기 위해 오버레이 블렌드를 구현해야 합니다. 편의상, 오버레이 블렌드 구현에는 계층적 박스를 사용합니다.

    오버레이 블렌드는 모든 색상 구성 요소에 개별적으로 적용되어야 합니다. 따라서 링크를 세 가지 색상 구성 요소로 모두 분리해야 합니다. 오버레이 블렌드는 다시 한 번 계층적 상자 안에 배치됩니다. 따라서 현재 계층적 상자 안에는 세 개의 계층적 상자가 있습니다. 복사 및 붙여넣기를 사용하여 각 색상 구성 요소에 대한 상자를 복제할 수 있습니다.

    VisualApplets 연산자를 사용하여 위에서 제시된 방정식을 구현하는 데에는 다양한 방법이 있을 것입니다. 일반적으로, 방정식을 구현하기 전에 항상 FPGA 사용에 맞게 조정하고 최적화해야 합니다.

    이 방정식에는 상수 값을 사용하는 곱셈과 나눗셈이 포함되어 있습니다. 이러한 연산은 VisualApplets 에서 사용할 수 있지만, FPGA에서는 매우 효율적으로 구현하기 어렵습니다. 곱셈이나 나눗셈을 2의 거듭제곱 곱셈으로 표현할 수 있다면, 간단한 비트 시프트를 사용하여 구현할 수 있습니다. 비트 시프트는 자원을 전혀 소모하지 않습니다! 이를 단순화해 보겠습니다.

    에서

    이는 7비트만큼 오른쪽으로 단순 이동하는 것으로, 즉 최하위 7비트를 버리는 것입니다.

    다음으로, 방정식에는 255에서 ColorA를 뺀 것과 같은 부분이 있습니다. 이는 단순한 색상 반전입니다. 흰색이 어두운 색으로, 어두운 색이 흰색으로 바뀝니다. 각 비트를 간단히 반전시키는 방법으로도 값을 반전시킬 수 있습니다. 이를 통해 마침내 방정식을 다음과 같이 다시 쓸 수 있습니다:

    식 2. FPGA 구현을 위한 최적화된 오버레이 블렌드


    이제 구현을 시작할 수 있습니다. 식에 포함된 나머지 연산들은 VisualApplets 연산자로 사용할 수 있습니다. 다음이 필요할 것입니다.

    • IF

    • 역전 현상과 관련 없음

    • 2^7로 나누기 위해 ShiftRight를 사용합니다.

    • 곱셈 연산을 위한 HWMULT

      HWMULT 외에도 ‘ VisualApplets ’에는 MULT 연산자가 포함되어 있습니다. 두 연산자는 동일한 기능을 수행하지만, HWMULT는 FPGA 내의 전용 곱셈기를 사용하므로 훨씬 적은 리소스만 필요합니다.

    • 비트 심도 제한을 처리하기 위해서는 CastBitWidth 연산자가 필요합니다. 이 연산자를 사용하면 최상위 비트(MSB)를 버림으로써 9비트에서 8비트로 변환할 수 있습니다. 수식에서 알 수 있듯이, 255보다 큰 값은 존재하지 않을 것입니다.

  4. 시뮬레이션을 이용한 검증

    1. VisualApplets 시뮬레이션을 사용하면 오버플로 블렌드의 기능을 쉽게 확인할 수 있습니다. 두 개의 시뮬레이션 소스를 사용하여 두 카메라 모두에 이미지를 입력하세요. 원하는 링크에 시뮬레이션 프로브를 배치하세요. 시뮬레이션 결과에서는 두 이미지가 오버레이된 모습을 확인할 수 있습니다. 원하신다면 계층적 상자에서 오버레이의 중간 결과도 확인해 볼 수 있습니다.

    2. 시뮬레이션만으로는 동기화 검증이 불가능합니다. 시뮬레이션은 애플릿의 기능적인 부분만 반영할 뿐, 타이밍은 반영하지 않기 때문입니다. 하드웨어를 통한 검증이 필요합니다.
  5. 트리거 추가하기

    앞서 언급했듯이, 버퍼 중 하나에서 오버플로가 발생하지 않도록 두 카메라 모두 동일한 프레임 속도로 작동해야 합니다. 이는 트리거 시스템을 사용하면 쉽게 해결할 수 있습니다.

Multiplex the Images of Two Cameras

VisualApplets 에서 이미지나 라인을 멀티플렉싱하는 것은 매우 쉽습니다. 먼저 두 대의 카메라 이미지를 멀티플렉싱하는 예제로 시작해 보겠습니다. 즉, 동일한 DMA 채널을 사용하여 카메라 A와 카메라 B의 이미지를 번갈아 가며 출력하고자 합니다.

  1. 기본 연산자

    카메라 모듈 2개, 버퍼 2개, DMA 1개를 사용하는 2대의 카메라를 위한 표준 설계가 필요합니다.

  2. 멀티플렉스 이미지

    이미지를 다중화하기 위해 InsertImage 연산자를 사용합니다. 이 연산자는 입력 이미지의 이미지를 차례대로 전달합니다. 예를 들어, 두 개의 입력을 사용하는 경우, 이 연산자는 입력 0, 1, 0, 1, 0, 1, ...의 이미지를 순서대로 전달합니다. 따라서 한 입력의 처리가 완료되면 다음 입력이 사용됩니다. 따라서 두 입력의 프레임 수가 동일해야 하며, 즉 입력의 프레임 속도가 같아야 합니다.

    보시다시피, 삽입 연산자 앞에 이미지 버퍼 모듈을 배치했습니다. 이는 InsertImage 연산자 자체에는 버퍼가 없기 때문입니다. 입력 0의 이미지는 전달되지만, 입력 1은 차단되므로 데이터 손실을 방지하기 위해 카메라 이미지를 버퍼링해야 합니다.

    각 입력(I0, I1, ..)에 대해 연산자는 Ins0, Ins1, ...이라고 하는 두 번째 입력을 제공합니다. 이 입력은 이미지를 사용할지 버릴지를 제어하는 제어 입력입니다. 따라서 Ins 입력에 값 0이 주어지면 해당 입력을 건너뛸 수 있으며, 값 1이 주어지면 해당 입력이 사용됩니다. 입력 그룹 I와 Ins는 동기적이어야 합니다. 즉, 동일한 M형 연산자를 통해 임의의 O형 연산자 네트워크를 거쳐 공급되어야 합니다. 자세한 내용은 ‘연산자 유형’을 참조하십시오. 두 입력 모두 동기적이므로, 동일한 이미지 크기를 가져야 합니다. InsertImage Ins 입력의 첫 번째 픽셀을 사용하여 이미지를 사용할지 버릴지 결정합니다. 이전 스크린샷에서 볼 수 있듯이, 우리는 단순히 CONST 연산자를 사용하여 이미지 사용을 활성화했습니다. CONST 연산자의 출력 링크 비트 심도를 1비트로 설정하고 매개변수 "Value"를 1로 설정하여 삽입을 활성화하십시오.

    주의: Ins 입력 중 하나의 값이 0인 경우에도, 운영자는 해당 입력에 대한 이미지를 여전히 처리해야 합니다. 값이 0이라고 해서 이미지를 제공할 필요가 없다는 뜻은 아닙니다. 입력에 이미지가 제공되지 않은 경우, 운영자는 이미지가 준비될 때까지 대기합니다.

    앞서 언급했듯이, 입력 중 하나는 한 번에 하나씩만 열리고, 나머지는 차단됩니다. 이미지는 예를 들어 서로 다른 버퍼에서와 같이 비동기적으로 가져와야 합니다. 다음 그림에서는 작동하지 않는 두 가지 구성을 볼 수 있습니다. 애플릿이 스스로를 차단하고 있으므로 아무런 결과도 얻을 수 없습니다. 이를 이른바 “교착 상태”라고 합니다.

    다음 기능을 사용한 교착 상태 구성 InsertImage

    그림 209. 다음을 사용한 교착 상태 구성 InsertImage


    한 입력 신호가 정지 상태일 때 다른 입력 신호가 활성 상태인 경우, 해당 입력 신호 중 하나를 버퍼링할 수 있는지 항상 확인하십시오. 데드락 상황은 DRC나 시뮬레이션을 통해 감지할 수 없다는 점을 잊지 마십시오. 데드락에 대한 자세한 내용은 ‘타이밍 동기화’에서 확인할 수 있습니다 .

두 대의 카메라 스티칭

이전 섹션에서는 두 대의 카메라 영상을 멀티플렉싱했습니다. 스티칭도 거의 같은 방식으로 이루어집니다. 대신 InsertLine 연산자를 사용하며, AppendLine 연산자를 통해 두 개의 연속된 라인을 이어 붙여야 합니다.

InsertLine은 먼저 두 입력의 줄을 다중화한 다음, 두 줄을 추가해야 합니다.

물론, 마지막 두 예제에서도 동일한 이미지 소스를 사용할 수 있습니다. 유일하게 주의해야 할 점은 삽입 전에 충분한 버퍼가 확보되어 있어야 한다는 것입니다. 이미지를 삽입하려면 전체 이미지를 버퍼링해야 합니다. 한 줄을 복제하는 경우에는, 다른 경로에서 동일한 줄이 처리되는 동안 해당 줄 중 하나만 버퍼링하면 됩니다. 몇 줄만 버퍼링하려면 ImageFifo 연산자를 사용할 수 있습니다. 이 연산자는 프레임 그래버의 DRAM 메모리를 사용하지 않습니다. 대신 FPGA 내부의 BlockRAM 메모리를 사용합니다. FIFO를 최대 한 줄만 저장하도록 구성할 것입니다. 다음 예제에서는 이미지 한 줄을 복제했으며, 이때 복제된 이미지는 반전되어 있습니다. 따라서 왼쪽에는 원본 이미지가, 오른쪽에는 반전된(네거티브) 버전이 표시됩니다.

줄 중복

그림 210. 줄 중복